package visit

import (
	"io/fs"
	"path/filepath"
	"strings"
	"time"

	"gitee.com/linxing_3/sr-core/utils/crypto"
)

type FileInfo struct {
	RootPath string    // 根路径 (扫描路径)
	Path     string    // 文件绝对路径
	Name     string    // 文件名称
	Size     int64     // 文件大小(Byte)
	Hash     string    // 文件哈希
	Ext      string    // 文件后缀
	FileType FileType  // 文件类型
	ModTime  time.Time // 文件修改时间
	IsDir    bool      // 是否是文件夹
}

func NewFileInfo(path string, info fs.FileInfo) *FileInfo {

	f := &FileInfo{
		Path:     path,
		Name:     info.Name(),
		Size:     info.Size(),
		ModTime:  info.ModTime(),
		Ext:      filepath.Ext(path),
		FileType: ParseFileType(path),
	}
	f.Hash, _ = crypto.Hash256File(path)
	return f
}

type FileType int

const (
	FileTypeUnknown FileType = iota
	FileTypeVideo
	FileTypeAudio
	FileTypeImage
	FileTypePPT
	FileTypeWord
	FileTypeExcel
	FileTypePDF
	FileTypeMarkdown
	FileTypeText
	FileTypeCode
	FileTypeOther
	FileTypeCsv
)

// ParseFileType 根据文件后缀解析文件类型
func ParseFileType(ext string) FileType {
	realExt := strings.TrimLeft(filepath.Ext(ext), ".")

	if realExt == "" {
		return FileTypeUnknown
	}

	switch lext := strings.ToLower(realExt); lext {
	case "jpg", "jpeg", "png", "gif", "bmp":
		return FileTypeImage
	case "mp4", "avi", "mkv", "flv", "mov", "wmv", "rmvb", "rm", "3gp", "webm":
		return FileTypeVideo
	case "mp3", "wav", "flac", "aac", "m4a":
		return FileTypeAudio
	case "ppt", "pptx":
		return FileTypePPT
	case "csv":
		return FileTypeCsv
	case "doc", "docx":
		return FileTypeWord
	case "xls", "xlsx":
		return FileTypeExcel
	case "pdf":
		return FileTypePDF
	case "md":
		return FileTypeMarkdown
	case "txt":
		return FileTypeText
	case "go", "py", "java", "c", "cpp", "js", "ts", "html", "css", "php", "rb", "swift", "kt", "scala", "rs", "dart", "pl", "lua", "r", "m", "h", "mm":
		return FileTypeCode
	default:
		return FileTypeOther
	}
}
